/*
For four-way set associative cache the state bits are:
b01 b02 b03 b12 b13 b23
and are encoded in CurrentState and NextState [5:0] in that order.
*/

module LRU(PS,Way,Reset,Access,NS,LRU);
input [5:0] PS;
input [1:0] Way;
input Reset, Access;
output[5:0] NS;
output [3:0] LRU;
reg [5:0] NS;	 	 	 	 	 	 // Present State and Next State;
reg [1:0] LRU;
reg [5:0] InitialState = 6'b000000;     // 0<1<2<3
parameter b01 = 5;
parameter b02 = 4;
parameter b03 = 3;
parameter b12 = 2;
parameter b13 = 1;
parameter b23 = 0;
//
//
//  When Access is asserted, compute current LRU and next permutation (state).
//
//  Small optimization: don't need to recompute LRU or next state if no access -- possible
//  energy savings.  (State won't change with repeated, unchanged input -- will only change
//  with change in accessed way).  Assumes that Access goes low between successive accesses.
//
//  Otherwise put Way in sensitivity list and use continuous assignment statement for LRU[i].
//
//
// could make these masks and complement to set as well as test
always @(posedge Access)
begin
  casex(PS)
    6'b000xxx: begin    // LRU = way 0
      LRU = 2'b00;
      end
    6'b1xx00x: begin    // LRU = way 1
      LRU = 2'b01;
    end
    
    6'bx1x1x0: begin    // LRU = way 2
      LRU = 2'b10;
    end
    
    6'bxx1x11: begin    // LRU = way 3
      LRU = 2'b11;
    end
    default: LRU = 2'bzz;
  endcase          
	  
	  //  Set all b(k,j) (where k < j), clear all b(j,k) (where k > j).
	  NS = PS;	 	 // only change the bits we need to
		case (Way)
			 0: begin
				NS[b01] = 1;
				NS[b02] = 1;
				NS[b03] = 1;
			end
			 1: begin
				NS[b01] = 0;
				NS[b12] = 1;
				NS[b13] = 1;
			end
					
			 2: begin
				NS[b02] = 0;
				NS[b12] = 0;
				NS[b23] = 1;
			end

			 3: begin
				NS[b03] = 0;
				NS[b13] = 0;
				NS[b23] = 0;
			end
		endcase
  end
	 	
endmodule